#include "LineEditView.h"

#include "LineToolBar.h"

#include "mcore/tools/EditWidget.h"
#include "mcore/tools/ConstVar4MapTool.h"


#include "mcore/tools/pick/PickToolByPoint.h"
#include "mcore/tools/pick/PickToolByRect.h"
#include "mcore/tools/pick/putils/PickEdgeByPoly.h"
#include "mcore/tools/pick/putils/PickVertexByPoly.h"

#include "mcore/tools/identify/IdentifyToolByRect.h"


#include"mcore/tools/mutils/GeometryHashCode.h"
#include "mcore/tools/setting/IdBtnToMapTool.h"
#include "mcore/tools/setting/KeToolSettings.h"




#include "../tpop/PWindowDrawType.h"
#include "../tpop/PWindowDrawType.h"


#include "../IdRootMenu.h"
#include "../MenuIdConvert.h"

#include "../../uitools/vhc/constview4fun.h"

#include <geostyle/xmls/SldParser.h>
#include <geostyle/styling/UserStyle.h>

#include <QFontDatabase>
#include <QSpacerItem>
#include <QTimer>


// std
#include <stdint.h>

#include <memory>



#include <cstring>
#include <memory>
// #include <fstream>


namespace kepen {
namespace core {

LineEditView::LineEditView(QWidget *parent,int lineOrPolygon,KeSysSetting *config)
    : QVBoxLayout{parent}
    ,m_LineTag(lineOrPolygon)
    ,sysConfig(config)
{
    setDirection(QBoxLayout::TopToBottom);
    setSpacing(0);
    setContentsMargins(0, 0, 0, 0);
    setAlignment(Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop);



    mapSurface = dynamic_cast<kepen::core::MapObject*>(parent);

    fontLabel.setPointSize(TextSize_Tool);
    int fontId = QFontDatabase::addApplicationFont(config->configView()->fileIconFont);
    QString fontName = QFontDatabase::applicationFontFamilies(fontId).at(0);
    QFont fontIcon = QFont(fontName);
    fontIcon.setPointSize(TextSize_IconFont);

    thirdFontIcon = fontIcon;

    std::size_t countFirst,countSecond;
    int menuFirst[]={ Goback_BarBtnId, FileSave_BtnId, 0x99000f,0x9a0102, EditTool_Vector, EditTool_LineSlide,
                       EditTool_LineExtrude,0x99000f,

                       EditTool_Pan, EditTool_Zoom, EditTool_Shear, EditTool_Rotate, 0x990012,
                       Pick_Target_Vertex, Pick_Target_Edge, 0x990016, IdentifyPick_ComboBox, 0x99000f,
                       MapTool_Protractor, 0x99000f, ClipGeometry,0x990002};

    int menuSecond[]= {0x990004,0x9a0101, DrawTool_Polygon, DrawTool_RectShape, DrawTool_Circle,
                        0x990012,ArrayAddVertexByString,
                        0x990012, 0x9a0103,  IdentifyLoad_ComboBox,
                        0x990008,EditLayerOther,0x99000f,
                        SetNULL_Geom, 0x990012, CleanSelected_BtnId,
                        0x990008,Option_MakeHole,
                        0x990008, Option_EnSnapGraphic,
                        0x990008, Option_VisibleVertexIndex, 0x990002 };

    countFirst =  sizeof(menuFirst)/sizeof(menuFirst[0]);
    countSecond = sizeof(menuSecond)/sizeof(menuSecond[0]);
    //
    if(IS_EditTab_Line(lineOrPolygon)){
        std::size_t k = 0;
        for(;k<countSecond;++k){
            if(DrawTool_Polygon == menuSecond[k])
            {
                menuSecond[k] = DrawTool_Polyline;

            }else if(Option_MakeHole == menuSecond[k]){
                std::size_t q = 1+ k;
                int n = menuSecond[q];
                menuSecond[k] = 0x990002;
                if(IS_WhiteSpaceBar(n)){
                    menuSecond[q] = 0x990004;
                }

            }
        }


    }

    toolFirst = new LineToolBar(parent,this,menuFirst,countFirst);
    toolSecond = new LineToolBar(parent,this,menuSecond,countSecond);
    toolFirst->setObjectName("LineEditToolBar01");
    toolSecond->setObjectName("LineEditToolBar02");
    addWidget(toolFirst);
    // addSpacing(1);
    addWidget(toolSecond);

    EditWidget * ew  = mapSurface->getEditWidgetSingleton();
    wkbWriter = new geos::io::WKBWriter(uint8_t(2));
    m_EditParam = new EditViewParamTag(ew);

    mapSurface->setActivateTool(NULL);

    QTimer::singleShot(100, this, &LineEditView::testTimer);
}

LineEditView::~LineEditView()
{
    /*
    QLayoutItem *child;
    QWidget *wg_ch;
    while ((child = takeAt(0)) != nullptr) {
        wg_ch = child->widget();
        if(wg_ch)
            delete child->widget();
        delete child;
    }*/
    // QLayout* layoutPtr = layout();
    // if(layoutPtr){
    //     int i,count = layoutPtr->count();
    //     for ( i = count-1; i >=0; --i){
    //         QLayoutItem * itt=  layoutPtr->takeAt(i);
    //         if(false == (nullptr ==itt)){
    //             QWidget *ww=  itt->widget();
    //             if(false == (nullptr ==ww)){
    //                 delete ww;
    //             }
    //             delete itt;
    //         }
    //     }
    // }

    // mapSurface->setActivateTool(NULL);//tool的parent是本类，没有意义，只是添乱
    if(wkbWriter)
    {
        delete wkbWriter;
        wkbWriter = NULL;
    }
    delete m_EditParam;
    m_EditParam = NULL;

}

void LineEditView::testTimer()
{
    //EditTool_Vector
    //IdentifyMode_Rect  Pick_Target_Edge IdentifyMode_Polygon
    // onBtnClicked(IdentifyMode_Polygon);
    // onBtnClicked(EditTool_Vector);
    // onBtnClicked(MapTool_Protractor);
    // onBtnClicked(ClipGeometry);

}

void LineEditView::repaintToolBar()
{
    // toolFirst->repaint();
    // toolSecond->repaint();
    mapSurface->repaint();
}

int LineEditView::onComboxClicked(int id, int flag,const QPoint &point)
{
    EditViewParamTag * evt = getEditViewParamRun();
    if(IdentifyPick_ComboBox == id){
        if(Pos_ComboBox_Right == flag)
        {
            // QPoint p1 = QCursor::pos();
            QWidget *parent = toolFirst;
            int checkedId = evt->ActDrawMode4Pick;


            PWindowDrawType *wPopup = new PWindowDrawType(parent,checkedId,id,thirdFontIcon);

            connect(wPopup, SIGNAL(selectedDrawToolSignals(QWidget*,int,int)),
                    this,SLOT(onSelectedViewDraw(QWidget*,int,int)),
                    Qt::ConnectionType(Qt::DirectConnection|Qt::SingleShotConnection));

            wPopup->show();
            wPopup->move(point);
        }else{


            bool hasGeom=false;
            kepen::core::MapObject * &mapObj = mapSurface;
            kepen::core::EditWidget* ew = mapObj->getEditWidgetSingleton();
            kepen::core::Graphic *grEdit = ew->getEditGraphicR0();
            if (grEdit != NULL
                && grEdit->getGeom() != NULL
                && grEdit->getGeom()->isEmpty() == false)
            {
                hasGeom = true;
            }

            if(hasGeom)
            {
                int idVal = evt->nDrawMode4Pick_last;
                onBtnIdenty4Pick(idVal);
            }
        }
    }else if(IdentifyLoad_ComboBox == id){
        if(Pos_ComboBox_Right == flag)
        {
            // QPoint p1 = QCursor::pos();
            QWidget *parent = toolSecond;
            int checkedId = evt->IdentifyDraw4Load;

            PWindowDrawType *wPopup = new PWindowDrawType(parent,checkedId,id,thirdFontIcon);

            connect(wPopup, SIGNAL(selectedDrawToolSignals(QWidget*,int,int)),
                    this,SLOT(onSelectedViewDraw(QWidget*,int,int)),
                    Qt::ConnectionType(Qt::DirectConnection| Qt::SingleShotConnection));

            wPopup->show();
            wPopup->move(point);
        }else{

            int idVal = evt->nIdentify4Load_last;
            onIdentifyLoad(idVal);
        }
    }
    return ViewClickFlag_RepaintRoot;
}

int LineEditView::onBtnClicked(int id)
{
    int retFlag = (IS_Close_Tab(id)
                   || MapTool_Protractor == id
                   || ClipGeometry == id
                   || LocationCombox == id)?ViewClickFlag_Go:0;

    bool isRepaintRoot = true,hasGeom=false;
    kepen::core::MapObject * &mapObj = mapSurface;
    kepen::core::EditWidget* ew = mapObj->getEditWidgetSingleton();
    kepen::core::Graphic *grEdit = ew->getEditGraphicR0();
    if (grEdit != NULL
        && grEdit->getGeom() != NULL
        && grEdit->getGeom()->isEmpty() == false) {
        hasGeom = true;
    }
    if(MapTool_Protractor==id)
    {
        if(hasGeom)
        {

            EditViewParamTag *editParam = m_EditParam;
            editParam->resetState();




        }
    }else if(ClipGeometry == id){
        if(hasGeom)
        {

            EditViewParamTag *editParam = m_EditParam;
            editParam->resetState();



        }
    }
    else if(IS_DrawTool_By(id)){
        onBtnDrawTool(id);
    }else if(IS_EditTool_By(id)){
        if(hasGeom)
            onBtnEditTool(id);
    }else if(Pick_Target_Vertex == id || Pick_Target_Edge == id){
        if(hasGeom)
            onBtnPickTarget(id);
    }else if(CleanSelected_BtnId == id)
    {
        std::size_t numVertex = ew->clearSelectedVertex();
        if(numVertex)
        {
            mapObj->repaint();
        }
    }else if(Option_EnSnapGraphic == id)
    {
        KeToolSettings *keSetting = ew->getMapToolSettings();
        keSetting->m_EnSnapGraphic = !keSetting->m_EnSnapGraphic;

    }
    else if(Option_MakeHole ==id){
        isRepaintRoot = false;


        if(grEdit){
            const geos::geom::Geometry * geomOld = grEdit->getGeom();
            if(geomOld && false == geomOld->isEmpty()){
                EditViewParamTag *editParam =this->m_EditParam;
                editParam->m_IsOptMakeHole = !editParam->m_IsOptMakeHole;
            }
        }
    }else if(Option_VisibleVertexIndex ==id){
        isRepaintRoot = false;

        if(grEdit){
            const geos::geom::Geometry * geomOld = grEdit->getGeom();
            if(geomOld && false == geomOld->isEmpty()){

                 KeToolSettings *keSettingRR2 = ew->getMapToolSettings();
                keSettingRR2->m_visibleVertexIndex = !keSettingRR2->m_visibleVertexIndex;
                mapObj->repaint();
            }
        }

    }
    if(isRepaintRoot)retFlag |= ViewClickFlag_RepaintRoot;
    return retFlag;
}

void LineEditView::onBtnDrawTool(int id){
    EditViewParamTag *editParam =this->m_EditParam;
    int val = editParam->ActNewDraw;

    if(val == id){

        editParam->setActGeomNew(NoneToggleValue);
        mapSurface->setActivateTool(NULL);
        mapSurface->repaint();
    }else{
        kepen::core::DrawTool::DrawType nDrawType = MenuIdConvert::GetDrawTypeByID(id);

        editParam->setActGeomNew(id);

        doActDrawToolImpl(nDrawType);
    }
}

void LineEditView::onBtnEditTool(int id)
{
    EditViewParamTag *editParam =this->m_EditParam;
    int val = editParam->ActGeomEdit;

    if(val == id){

        editParam->setActGeomNew(MenuId_None);
        mapSurface->setActivateTool(NULL);
        mapSurface->repaint();
    }else{



        if(false == (0 == editParam->m_HashGeom_run))
        {
            // kepen::core::EditWidget* ew = mapSurface->getEditWidgetSingleton();
            editParam->setActGeomEdit(id);
            actEditTool(id,false);
        }else
        {

            mapSurface->repaint();
        }
    }
}

void LineEditView::onBtnPickTarget(int nIdPickTarget)
{
    EditViewParamTag *editParam =this->m_EditParam;
    int val = editParam->VertexOrEdgeTarget4Pick;

    mapSurface->getEditWidgetSingleton()->getEditPointLayer()->clearData();

    if(val == nIdPickTarget){
        editParam->clearPickMode();
        mapSurface->setActivateTool(NULL);
        mapSurface->repaint();
    }else{
        int nDrawMode4Pick = editParam->setTarget4Pick(nIdPickTarget);
        //Pick_Target_Vertex == id || Pick_Target_Edge == id
        doActPickToolImpl(nDrawMode4Pick,nIdPickTarget);


    }
}

void LineEditView::onBtnIdenty4Pick(int idVal)
{
    EditViewParamTag *editParam =this->m_EditParam;
    int val = editParam->ActDrawMode4Pick;

    if(val == idVal){
        editParam->clearPickMode();
        mapSurface->getEditWidgetSingleton()->getEditPointLayer()->clearData();
        mapSurface->setActivateTool(NULL);
        mapSurface->repaint();
    }else{
        int nVertexOrEdge = editParam->setDrawMode4Pick(idVal);
        doActPickToolImpl(idVal,nVertexOrEdge);

        // qDebug()  <<__FILE__ <<",Line:"<<__LINE__ <<" , ("<< id<<","<<nVertexOrEdge;

    }
}

void LineEditView::onIdentifyLoad(int idVal)
{
    EditViewParamTag *editParam =this->m_EditParam;
    int val = editParam->IdentifyDraw4Load;

    if(val == idVal){
        kepen::core::MapObject * &mapObj = mapSurface;
        editParam->clearPickMode();
        mapObj->getEditWidgetSingleton()->getEditPointLayer()->clearData();
        mapObj->setActivateTool(NULL);
        mapObj->repaint();
    }else{
        editParam->setIdentify4Load(idVal);
        if(IdentifyPick_ByPolygon ==idVal)
        {
            kepen::core::DrawTool::DrawType nDrawPolygon
                = kepen::core::DrawTool::DrawType::Polygon;
            kepen::core::DrawTool::Draw4Shape ds = kepen::core::DrawTool::Draw4Shape::Identify4LoadMemory;
            kepen::core::MapObject * &mapObj = mapSurface;
            kepen::core::DrawTool *tool = new kepen::core::DrawTool(this,nDrawPolygon,ds);
            tool->activate(mapObj);

            connect(tool, SIGNAL(onDrawCompletedSignals(kepen::core::DrawTool*)),
                    this,SLOT(onDrawPolygon4Load(kepen::core::DrawTool*)),
                    Qt::DirectConnection);
            // not | Qt::SingleShotConnection

            mapObj->repaint();
        }
        else
        {


            kepen::core::MapObject * &mapObj = mapSurface;

            IdentifyToolByRect *tool;
            BaseMapTool *bt=mapObj->createToolByBtnID(this,idVal,false);
            tool = dynamic_cast<IdentifyToolByRect*>(bt);
            connect(tool, SIGNAL(onIdentifyToolSignals(kepen::core::IdentifyToolByRect*)),
                    this,SLOT(onIdentifyByRect(kepen::core::IdentifyToolByRect*)),
                    Qt::DirectConnection);
            // not | Qt::SingleShotConnection

            // tool->activate(mapObj);

            mapObj->repaint();
        }


        // qDebug()  <<__FILE__ <<",Line:"<<__LINE__ <<" , ("<< id<<","<<nVertexOrEdge;

    }
}

void LineEditView::doActPickToolImpl(int nDrawMode4Pick,int nIdVertexOrEdge)
{
    SnapOption vertexOrEdge = Pick_Target_Vertex == nIdVertexOrEdge ? SnapOption::VERTEX:SnapOption::EDGE;
    if(IdentifyPick_ByPoint == nDrawMode4Pick){

        PickToolByPoint *ptp = new PickToolByPoint(this,vertexOrEdge);
        ptp->activate(mapSurface);
    }else if(IdentifyPick_ByRect == nDrawMode4Pick){

        PickToolByRect *ptp = new PickToolByRect(this,vertexOrEdge,isCompatibleClick_No,PickToolByRect::BoxByType::BoxByRect);
        ptp->activate(mapSurface);
    }else if(IdentifyPick_ByCircle == nDrawMode4Pick){

        PickToolByRect *ptp = new PickToolByRect(this,vertexOrEdge,isCompatibleClick_No,PickToolByRect::BoxByType::BoxByCircle);
        ptp->activate(mapSurface);
    }else if(IdentifyPick_ByPolygon == nDrawMode4Pick){
        doActPickByPolygon(vertexOrEdge);
    }
    mapSurface->repaint();
}

void LineEditView::doActPickByPolygon(SnapOption vertexOrEdge)
{
    kepen::core::DrawTool::DrawType nDrawPolygon
        = kepen::core::DrawTool::DrawType::Polygon;
    kepen::core::DrawTool::Draw4Shape ds = SnapOption::VERTEX == vertexOrEdge?kepen::core::DrawTool::Draw4Shape::PickVertex: kepen::core::DrawTool::Draw4Shape::PickEdge;
    kepen::core::MapObject * &mapObj = mapSurface;
    kepen::core::DrawTool *tool = mapObj->createDrawTool(this,nDrawPolygon,ds);
    // tool->activate(mapObj);

    connect(tool, SIGNAL(onDrawCompletedSignals(kepen::core::DrawTool*)),
            this,SLOT(onDrawPolygon4Pick(kepen::core::DrawTool*)),
            Qt::DirectConnection);
    // not | Qt::SingleShotConnection

    mapObj->repaint();
}

void LineEditView::doActDrawToolImpl(kepen::core::DrawTool::DrawType nDrawType)
{
    kepen::core::MapObject * &mapObj = mapSurface;
    kepen::core::DrawTool *tool = mapObj->createDrawTool(this,nDrawType,kepen::core::DrawTool::Draw4Shape::NewGeometry);
    // tool->activate(mapObj);

    connect(tool, SIGNAL(onDrawCompletedSignals(kepen::core::DrawTool*)),
            this,SLOT(onDrawCompletedHandler(kepen::core::DrawTool*)),
            Qt::ConnectionType(Qt::DirectConnection  | Qt::SingleShotConnection));
    mapObj->repaint();
}

void LineEditView::onDrawCompletedHandler(kepen::core::DrawTool*tool)
{
    kepen::core::DrawTool::Draw4Shape dd = tool->getData();
    if(kepen::core::DrawTool::Draw4Shape::NewGeometry == dd )
    {

        EditViewParamTag *editParam =this->m_EditParam;

        onDrawFinishedHandler(tool);
        onGeometryChanged();


        if(false == (0 == editParam->m_HashGeom_run))
        {
            editParam->setActGeomEdit(EditTool_Vector);
            actEditTool(EditTool_Vector,false);
        }else
        {
            mapSurface->repaint();
        }

    }



}

void LineEditView::onDrawPolygon4Pick(kepen::core::DrawTool *tool)
{
    std::unique_ptr<geos::geom::Geometry> geomNew = tool->getDrawCompleted();
    Qt::KeyboardModifiers kms = QGuiApplication::keyboardModifiers();
    bool isKeyboardShift = Qt::KeyboardModifier::ShiftModifier  == (Qt::KeyboardModifier::ShiftModifier & kms);

    if(geomNew
        && geomNew.get()
        && false == geomNew->isEmpty()
        && geos::geom::GeometryTypeId::GEOS_POLYGON == geomNew->getGeometryTypeId())
    {

        kepen::core::DrawTool::Draw4Shape dd = tool->getData();
        if(kepen::core::DrawTool::Draw4Shape::Identify4LoadMemory == dd)
        {
            geos::geom::Polygon * poly = dynamic_cast<geos::geom::Polygon *>(geomNew.get());
            onIdentify4LoadImpl(poly,isKeyboardShift);
        }
        else if(kepen::core::DrawTool::Draw4Shape::PickVertex == dd
                 || kepen::core::DrawTool::Draw4Shape::PickEdge == dd)
        {

            geos::geom::Polygon * poly = dynamic_cast<geos::geom::Polygon *>(geomNew.get());

            const geos::geom::LinearRing*ring =poly->getExteriorRing();
            const geos::geom::CoordinateSequence *vs = ring->getCoordinatesRO();
            kepen::core::MapObject * &mapObj = mapSurface;
            kepen::core::EditWidget* ew = mapObj->getEditWidgetSingleton();
            // kepen::core::GraphicsLayer *gLayer = ew->getEditGrapicLayer();
            kepen::core::Graphic *grEdit = ew->getEditGraphicR0();
            const geos::geom::Geometry *geom = grEdit->getGeom();
            if(geom  && false == geom->isEmpty()){


                if(kepen::core::DrawTool::Draw4Shape::PickVertex == dd)
                {
                    PickVertexByPoly pvp(vs);
                    pvp.pickVertex(geom);

                    if(pvp.result.size()>0){
                        /*
                        for(const auto &kIt:pvp.result){
                            QString txt = QString::asprintf("coords:(%.6f,%.6f) (%.6f,%.6f) index:(%d,%d) index-ring:(%d,%d)",
                                                            kIt.x0,kIt.y0,kIt.x1,kIt.y1,
                                                            kIt.indexVertex,kIt.indexVertexR2,
                                                            kIt.indexOfRing,kIt.indexOfRingR2
                                                            );
                            qDebug().noquote()  <<__FILE__ <<",Line:"<<__LINE__ << txt;
                        }*/
                        ew->getEditPointLayer()->addList(pvp.result,isKeyboardShift);
                    }else{
                        // qDebug() <<__FILE__ <<",Line:"<<__LINE__ << "  pick Empty ----- ";
                        if(false == isKeyboardShift)
                            ew->getEditPointLayer()->clearData();
                    }
                }else if(kepen::core::DrawTool::Draw4Shape::PickEdge == dd)
                {
                    PickEdgeByPoly pvp(vs);
                    pvp.pickEdge(geom);

                    if(pvp.m_Result.size()>0){

                        ew->getEditPointLayer()->addList(pvp.m_Result,isKeyboardShift);
                    }else{
                        // qDebug() <<__FILE__ <<",Line:"<<__LINE__ << "  pick Empty ----- ";
                        if(false == isKeyboardShift)
                            ew->getEditPointLayer()->clearData();
                    }
                }


            }
            mapObj->repaint();

        }




    }


}


void LineEditView::onDrawPolygon4Load(kepen::core::DrawTool *tool)
{

}

void LineEditView::onDrawFinishedHandler(kepen::core::DrawTool*tool)
{
    std::unique_ptr<geos::geom::Geometry> geomNew = tool->getDrawCompleted();
    if(geomNew && geomNew.get() && false == geomNew->isEmpty()){


        kepen::core::MapObject * &mapObj = mapSurface;
        kepen::core::EditWidget* ew = mapObj->getEditWidgetSingleton();
        // kepen::core::GraphicsLayer *gLayer = ew->getEditGrapicLayer();
        kepen::core::Graphic *grEdit = ew->getEditGraphicR0();
        EditViewParamTag *editParam =this->m_EditParam;
        kepen::sld::SldParser parserSld;
        if(NULL == grEdit){
            std::unique_ptr<kepen::core::Graphic> gr(std::make_unique<kepen::core::Graphic>());
            geos::geom::GeometryTypeId t =  geomNew->getGeometryTypeId();
            if(geos::geom::GeometryTypeId::GEOS_POLYGON ==t)
            {
                QString cssPoly("{polygonOptions:{strokeWidth:2dp,strokeColor:#ddaa00,fillColor:#80008888}}");
                std::unique_ptr<kepen::sld::UserStyle> stylePoly = parserSld.ReadUserStyleCss(cssPoly);
                gr->setGeom(std::move(geomNew));
                gr->setStyle(std::move(stylePoly));
                // gLayer->addGraphic(std::move(gr));
                ew->setEditGraphic(std::move(gr));
            }else  if(geos::geom::GeometryTypeId::GEOS_LINESTRING ==t)
            {
                QString cssPoly("{polylineOptions:{strokeWidth:2dp,strokeColor:#DDAA00}}");
                std::unique_ptr<kepen::sld::UserStyle> styleLine = parserSld.ReadUserStyleCss(cssPoly);
                gr->setGeom(std::move(geomNew));
                gr->setStyle(std::move(styleLine));
                // gLayer->addGraphic(std::move(gr));
                ew->setEditGraphic(std::move(gr));
            }

        }
        else{
            const geos::geom::Geometry * geomOld = grEdit->getGeom();
            if(NULL == geomOld || geomOld->isEmpty())
            {
                grEdit->setGeom(std::move(geomNew));
            }else{
                geos::geom::GeometryTypeId t =  geomNew->getGeometryTypeId();
                if(geos::geom::GeometryTypeId::GEOS_POLYGON ==t)
                {
                    bool isMakeHole = editParam->m_IsOptMakeHole;
                    if(isMakeHole && geomOld->intersects(geomNew.get())){
                        std::unique_ptr<Geometry> geomR2 = geomOld->difference(geomNew.get());
                        if(geomR2 && geomR2.get()
                            && false == geomR2->isEmpty())
                        {
                            geos::geom::GeometryTypeId t2 =  geomR2->getGeometryTypeId();
                            if(geos::geom::GeometryTypeId::GEOS_POLYGON == t2
                                || geos::geom::GeometryTypeId::GEOS_MULTIPOLYGON == t2){
                                grEdit->setGeom(std::move(geomR2));
                            }else{
                                grEdit->setNullGeometry();
                            }
                        }else{
                            grEdit->setNullGeometry();
                        }
                    }else
                    {
                        int tt = m_LineTag;
                        if(IS_EditTab_Polygon(tt))
                        {
                            std::unique_ptr< geos::geom::Geometry> geomR3 =  geomOld->Union(geomNew.get());
                            grEdit->setGeom(std::move(geomR3));
                        }else
                        {
                            geomNew->normalize();

                            const  geos::geom::Geometry * cg = geomNew.get();
                            const  geos::geom::Polygon * cpPoly = dynamic_cast<const  geos::geom::Polygon*>(cg);
                            const  geos::geom::LinearRing* ring = cpPoly->getExteriorRing();
                            std::unique_ptr< geos::geom::Geometry> geomR3 =  geomOld->Union(ring);
                            grEdit->setGeom(std::move(geomR3));
                        }

                    }

                }else{
                    std::unique_ptr<Geometry> geomR3 =  geomOld->Union(geomNew.get());
                    grEdit->setGeom(std::move(geomR3));
                }
            }
        }




    }


}

void LineEditView::onIdentify4LoadImpl(const geos::geom::Polygon *poly,bool isKeyboardShift)
{

}


void LineEditView::onIdentifyByRect(kepen::core::IdentifyToolByRect *tool)
{
    IdentifyBoxCoords coords = tool->getIdentifyCoords();
    QString txt = QString::asprintf("coords:(%.4f,%.4f) (%.4f,%.4f) (%d,%d)",
                                    coords.xmin,coords.ymin,
                                    coords.xmax,coords.ymax,
                                    coords.isLeft2Right,coords.tRectOrCircle
                                    );
    qDebug().noquote()  <<__FILE__ <<",Line:"<<__LINE__ << txt;
}

void LineEditView::onSelectedViewDraw(QWidget *dlg, int id,int data)
{

    if(id > 0){

        if(IdentifyPick_ComboBox ==data)
        {
            onBtnIdenty4Pick(id);
        }
        else if(IdentifyLoad_ComboBox == data)
        {
            onIdentifyLoad(id);

        }
    }


    dlg->deleteLater();
}





void LineEditView::onGeometryChanged()
{
    kepen::core::MapObject * &mapObj = mapSurface;
    kepen::core::EditWidget* ew = mapObj->getEditWidgetSingleton();
    const  kepen::core::Graphic *grEdit = ew->getEditGraphic();
    EditViewParamTag *editParam =this->m_EditParam;
    if(grEdit)
    {

        const geos::geom::Geometry * geomResult = grEdit->getGeom();
        if(NULL == geomResult || geomResult->isEmpty()){
            editParam->m_IsOptMakeHole = false;
            editParam->m_HashGeom_run = 0;
        }else{
            /*
            std::stringstream result_stream;
            wkbWriter->setOutputDimension(MyGeomOutputDimension);
            wkbWriter->setByteOrder(geos::io::WKBConstants::byteOrder::wkbNDR);
            wkbWriter->setIncludeSRID(false);
            wkbWriter->writeHEX(*geomResult,result_stream);
            // result_stream.seekg(0);
            std::string actual = result_stream.str();
            std::hash<std::string> hash_fn;
            std::size_t hashNum = hash_fn(actual);
*/
            editParam->m_HashGeom_run = GeometryHashCode::hashCodeGeometry(geomResult,0);
        }
    }else{
        editParam->m_HashGeom_run = 0;
    }
}






EditViewParamTag * LineEditView::getEditViewParamRun(){
    return this->m_EditParam;
}

void LineEditView::actEditTool(int id, bool checkView)
{
    // MapObject * mapSurface =mapObj;
    if(false == IS_EditTool_Affine(id))
    {
        kepen::core::EditWidget* ew = mapSurface->getEditWidgetSingleton();
        ew->getEditPointLayer()->clearData();
    }

    BaseMapTool *t = mapSurface->createToolByBtnID(this,id,checkView);
    if(t){
      mapSurface->repaint();
    }


}


}
}
